//////////////////////////////////////////////////////////////////////
//!\file AlbumDataModel.cpp
//!\brief Scans start path for flac files, which are to be put into a
//!\brief vector aka album.
//!\brief Use the getter to obtain a vector of flac albums.
//!\author timmsusa@googlemail.com
//////////////////////////////////////////////////////////////////////

#include "AlbumDataModel.hpp"

#include <QDebug>
#include <QDirIterator>

AlbumDataModel::AlbumDataModel(const QString& path):
    m_Persistence(),
    m_DeepScanEnabled(m_Persistence.getEnableDeepScan()),
    m_Path(path),
    m_FlacAlbumList(),
    m_RequestStopScanDirs(false)
{
    if (!m_Path.isEmpty())
    {
        QDir dir(m_Path);
        if ( dir.exists() )
        {
            scanDirsForAlbum(dir);
        }
    }
}

AlbumDataModel::~AlbumDataModel()
{
    requestStopScanDirs();
}


void AlbumDataModel::initByPath(const QString& path)
{
    requestStopScanDirs();
    m_RequestStopScanDirs = false;
    m_FlacAlbumList.clear();
    m_Path.clear();
    m_Path = path;
    QDir dir(m_Path);
    if ( dir.exists() )
    {
        scanDirsForAlbum(dir);
    }
}

// Try to never ever change this method!
// Scans through folders. If file is found, check for fileendings
// and check for validity. If file is valid, add it to album.
// If new folder is found, add album to collection and create
// a new album for further processing.
void AlbumDataModel::scanDirsForAlbum(const QDir& dir)
{
    qDebug() << "AlbumDataModel::scanDirsForAlbum";

    // Clear list before insert.
    m_FlacAlbumList.clear();
    int cnt=0;

    // Run!
    QDirIterator iterator(dir.absolutePath(), QDirIterator::Subdirectories);
    Album *album = new Album;
    while (iterator.hasNext() && !m_RequestStopScanDirs)
    {
        iterator.next();

        if (iterator.fileInfo().isFile()) // File found.
        {
            QString dirPath = iterator.fileInfo().absolutePath();
            QDir myDir(dirPath);
            if (iterator.fileInfo().absoluteFilePath().endsWith(".flac")) // File is FLAC.
            {
                album->setPath(dirPath);
                album->setName(myDir.dirName());

                // Add track to album
                if (!m_DeepScanEnabled)
                {
                    album->addTrack(iterator.fileName());
                    //qDebug() << "QuickScan! " << iterator.fileName();
                }
                else
                {
                    addFlacTrackToAlbum(iterator.fileInfo(), *album);
                }
                ++cnt;
            }
        }

        // Add Album.
        if (iterator.fileInfo().isDir() && !album->getName().isEmpty())
        {
            addAlbum(*album);
            //qDebug() << "Album added: " << album->getName() << " Number of Tracks: " << cnt;
            cnt=0;
            delete album;
            album = new Album;
        }

        // This is necessary to catch the last found album.
        if (!iterator.hasNext())
        {
            addAlbum(*album);
            //qDebug() << "Last Album added: " << album->getName() << " Number of Tracks: " << cnt;
            cnt=0;
            delete album;
        }
    }

    emit sigInitFinished();
}

void AlbumDataModel::slotInitByPath(QString path)
{
    initByPath(path);
}

const QVector < Album >& AlbumDataModel::getAlbumList()const
{
    return m_FlacAlbumList;
}

void AlbumDataModel::requestStopScanDirs()
{
    m_RequestStopScanDirs = true;
}

void AlbumDataModel::addAlbum(const Album &album)
{
    if (!album.getTrackList().empty() && !m_DeepScanEnabled)
    {
        m_FlacAlbumList.push_back(album);
        emit sigFlacFound("FLAC Album found! " + album.getPath() );

    }
    else if (!album.getFlacTrackList().empty() && m_DeepScanEnabled)
    {
        m_FlacAlbumList.push_back(album);
        emit sigFlacFound("FLAC Album found! " + album.getPath() );
        //qDebug() << "FLAC Album found: " <<  album.getName() << " with size: " << album.getFlacTrackList().size();
    }
    else
    {
    }

}

void AlbumDataModel::addFlacTrackToAlbum(const QFileInfo fi, Album &album)
{
    QString filePath = fi.absoluteFilePath();

    if (FlacMetadataManager::isFlacValid(filePath))
    {
        QString metaMd5 = FlacMetadataManager::getTrackMd5ByPath(filePath);
        QString md5 = FlacMetadataManager::extractMd5(filePath);
        // qDebug() << "AlbumDataModel::addFlacTrackToAlbum " << md5  <<  " MusicFiles: " <<  fi.completeBaseName() << "MD5: " << metaMd5;
        FlacTrack  flacTrack( "" , md5, fi.completeBaseName() + ".flac",  metaMd5);
        album.addFlacTrack(flacTrack.get());
        //qDebug() << "DeepScan! " << flacTrack.m_File << " found!";
    }
}

void AlbumDataModel::slotDeepScanEnabled(bool enabled)
{
    qDebug() << "AlbumDataModel::slotDeepScanEnabled: " << enabled;
    m_DeepScanEnabled = enabled;
}

void AlbumDataModel::slotStopScanDirsRequested()
{
    qDebug() << "AlbumDataModel::slotStopScanDirsRequested";
    requestStopScanDirs();
}
